package com.qsw.fileoperatelib.encode;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 加密/解密
 */
public class EncodeUtil {
    /**
     * 取反加密/取反解密
     * 秘钥中符合规则的最少数量
     */
    public static final int REVERSAL_MIN_OK_COUNT = 5;

    /**
     * 取反加密/取反解密
     * 对指定字节按位取反
     *
     * @param file      待处理文件
     * @param secretKey 取反位置，长度必须大于{@link #REVERSAL_MIN_OK_COUNT}
     * @return true：成功；false：失败。至少{@link #REVERSAL_MIN_OK_COUNT}个位置成功才认为最终成功
     * @throws IOException 异常
     */
    public static boolean encodeDecodeReversal(File file, long[] secretKey) throws IOException {
        boolean result = false;
        if (!checkReversal(file, secretKey)) {
            return result;
        }

        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(file, "rw");
            for (long l : secretKey) {
                if (l < raf.length()) {
                    raf.seek(l);
                    byte readByte = raf.readByte();
                    raf.seek(l);
                    raf.writeByte(~readByte);
                }
            }
            result = true;
        } finally {
            if (raf != null) {
                raf.close();
            }
        }

        return result;
    }

    /**
     * 取反加密/取反解密
     * 检查文件及秘钥是否合格
     *
     * @param file      待处理文件
     * @param secretKey 取反位置，长度必须大于{@link #REVERSAL_MIN_OK_COUNT}
     * @return true：合格；false：不合格。至少{@link #REVERSAL_MIN_OK_COUNT}个位置满足才认为最终合格
     */
    private static boolean checkReversal(File file, long[] secretKey) {
        if (file == null || !file.exists() || !file.isFile() || secretKey == null || secretKey.length < REVERSAL_MIN_OK_COUNT) {
            return false;
        }

        // 判断秘钥是否合格
        int okCount = 0;
        for (long l : secretKey) {
            if (l >= 0 && l < file.length()) {
                okCount++;
            }
            if (okCount >= REVERSAL_MIN_OK_COUNT) {
                return true;
            }
        }

        return false;
    }
}
